package local.eken.misc;

import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.ini4j.Ini;

/**
 * Handles the various game preferences that is specified in settings.ini 
 * @author Gabriel Ekblad
 */
public class GamePreferences {
	final private static String INI_FILE_NAME = "settings.ini";
	final private static String SETTINGS_DIR = System.getProperty("user.dir") + "/cfg";
	
	final private static String PREF_SECTION = "preferences";
	final private static String PREF_RESOLUTION = "resolution";
	final private static String PREF_FULLSCREEN = "fullscreen";
	final private static String PREF_WINDOWMODE = "windowmode";
	final private static String DEFAULT_PREF_RESOLUTION = "640x480";
	final private static String DEFAULT_PREF_FULLSCREEN = "false";
	final private static String DEFAULT_PREF_WINDOWMODE = "true";
	
	private static GamePreferences theInstance = null;
	
	private Ini preferences;
	
	private Map<String, Object> options = new HashMap<String, Object>();
	
	public static GamePreferences getInstance() {
		if(GamePreferences.theInstance == null) {
			GamePreferences.theInstance = new GamePreferences(SETTINGS_DIR + "/" + INI_FILE_NAME);
		}

		return GamePreferences.theInstance;
	}
	
	private GamePreferences(String ini) {	
		try {
			this.preferences = new Ini(new File(ini));
		} catch (Exception e) {
			this.fallback();
		}
	}
	
	private void fallback() {
		File dir = new File(SETTINGS_DIR);
		
		if(!dir.isDirectory()) {
			dir.mkdir();
		}
		
		File ini = new File(SETTINGS_DIR + "/" + INI_FILE_NAME);
		
		if(!ini.exists()) {
			try {
				ini.createNewFile();
				Ini tmp = new Ini(ini);
				tmp.put(PREF_SECTION, PREF_RESOLUTION, DEFAULT_PREF_RESOLUTION);
				tmp.put(PREF_SECTION, PREF_FULLSCREEN, DEFAULT_PREF_FULLSCREEN);
				tmp.put(PREF_SECTION, PREF_WINDOWMODE, DEFAULT_PREF_WINDOWMODE);
				
				this.preferences = tmp;
			} catch(IOException e) {
				System.exit(1);
			}
		}
	}
	
	private boolean sectionExist(String section) {
		return this.preferences.get(section) == null ? false : true;
	}
	
	private String getOption(String section, String option) {
		return this.preferences.fetch(section, option);
	}
	
	/**
	 * Returns the specified resolution from settings.ini
	 * @return	Dimension of the specified resolution
	 */
	public Dimension getResolution() {
		if(!this.options.containsKey(PREF_RESOLUTION)) {
			if(!this.sectionExist(PREF_SECTION)) {
				this.preferences.add(PREF_SECTION);
			}
			
			String resolution = null;
			
			if((resolution = this.getOption(PREF_SECTION, PREF_RESOLUTION)) == null) {
				this.preferences.add(PREF_SECTION, PREF_RESOLUTION, DEFAULT_PREF_RESOLUTION);
				resolution = DEFAULT_PREF_RESOLUTION;
			}
			
			String sRes[] = resolution.split("x");
			int width = Integer.parseInt(sRes[0]);
			int height = Integer.parseInt(sRes[1]);
			
			this.options.put(PREF_RESOLUTION, new Dimension(width, height));
		}
		
		return (Dimension) this.options.get(PREF_RESOLUTION);
	}
	
	/**
	 * Checks if fullscreen is set.
	 * @return	true if fullscreen is desired, otherwise false.
	 */
	public boolean isFullscreen() {
		if(!this.options.containsKey(PREF_FULLSCREEN)) {
			if(!this.sectionExist(PREF_SECTION)) {
				this.preferences.add(PREF_SECTION);
			}
			
			String fullscreen = null;
			
			if((fullscreen = this.getOption(PREF_SECTION, PREF_FULLSCREEN)) == null) {
				this.preferences.add(PREF_SECTION, PREF_FULLSCREEN, DEFAULT_PREF_FULLSCREEN);
				fullscreen = DEFAULT_PREF_FULLSCREEN;
			}
			
			boolean isFullscreen = this.fromStringToBoolean(fullscreen);
			this.options.put(PREF_FULLSCREEN, isFullscreen);
		}
		
		return (boolean) this.options.get(PREF_FULLSCREEN);
	}
	
	/**
	 * Checks if windowmode is set.
	 * @return	true if windowmode is desired, otherwise false.
	 */
	public boolean isWindowMode() {
		if(!this.options.containsKey(PREF_WINDOWMODE)) {
			if(!this.sectionExist(PREF_SECTION)) {
				this.preferences.add(PREF_SECTION);
			}
			
			String windowmode = null;
			
			if((windowmode = this.getOption(PREF_SECTION, PREF_WINDOWMODE)) == null) {
				this.preferences.add(PREF_SECTION, PREF_WINDOWMODE, DEFAULT_PREF_WINDOWMODE);
				windowmode = DEFAULT_PREF_WINDOWMODE;
			}
			
			boolean isWindowMode = this.fromStringToBoolean(windowmode); 
			this.options.put(PREF_WINDOWMODE, isWindowMode);
		}
		
		return (boolean) this.options.get(GamePreferences.PREF_WINDOWMODE);
	}
	
	private boolean fromStringToBoolean(String bool) {
		return bool.equals("true") ? true : false;
	}
}
